<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Help - API Usage Instructions</title>
	<link href="/dc/css/bootstrap.min.css" rel="stylesheet">
	<style>
	    .command-intro {
	        background-color: #f8f9fa;
	        padding: 20px;
	        border-radius: 8px;
	        margin-bottom: 30px;
	        border-left: 4px solid #007bff;
	    }
	    .command-intro h5 {
	        margin-bottom: 15px;
	    }
	    .badge-required {
	        background-color: #dc3545;
	    }
	    .badge-optional {
	        background-color: #28a745;
	    }
	</style>
	<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
	  <symbol id="server" viewBox="0 0 16 16">
	    <path d="m12.14 8.753-5.482 4.796c-.646.566-1.658.106-1.658-.753V3.204a1 1 0 0 1 1.659-.753l5.48 4.796a1 1 0 0 1 0 1.506z"/>
	  </symbol>
	</svg>
</head>
<body>
    <div class="container my-5">
        <div class="text-center mb-4">
            <h1>Help - How to Call Cloud APIs</h1>
            <p class="text-muted">Data Flow: Your Application → Cloud Server → Your Application</p>
        </div>
		<div class="command-intro">
            <h5 class="card-title">Explanation of API Operation Mechanism</h5>
            <p>Interaction between your application and cloud server:</p>
            <ul>
                <li><strong>Your Application:</strong> Sends API requests to the cloud server, each request needs to carry api and key parameters.</li>
                <li><strong>Cloud Server:</strong> Validates the legality of the key, and after verification, returns the result specified by the api parameter.</li>
                <li><strong>Your Application:</strong> Receives the Json formatted return content from the cloud server.</li>
            </ul>
            <p>The actual call would be an HTTP request like this: <span th:text="${siteUrl} + '/dc/api/call?key=' + ${apiKey} + '&api=device'"></span></p>
			<p>Note that API calls have quotas, with limitations on the number of calls per minute and per day. Each API description below has a real-time test function. <a href="/dc/pub/doc?page=interface" target="_blank">Click here</a> for detailed information about Keys.</p>
        </div>

        <div class="accordion" id="apiAccordion">
            <!-- Accordion items will be dynamically inserted here -->
        </div>
    </div>

    <script src="/dc/js/bootstrap.bundle.min.js"></script>
    <th:block th:insert="~{fragments/nav :: scriptFunctions}"></th:block>

    <script th:inline="javascript">
		window.onload = function() {
			let i=1;
			createAccordionItem(i++, 'Run Command on Device', 'runcommand','command');
		    
			createAccordionItem(i++, 'Device List', 'devicelist','device');
		    createAccordionItem(i++, 'Device Add', 'deviceadd','device');
		    createAccordionItem(i++, 'Device Delete', 'devicedel','device');
		    createAccordionItem(i++, 'Device Name Update', 'devicenameupdate','device');
		    
		    createAccordionItem(i++, 'Module List', 'modulelist','module');
		    createAccordionItem(i++, 'Module Aggregated Information Query', 'aggreport','module');
		    createAccordionItem(i++, 'Module Historical Information Query', 'historydata','module');
		    createAccordionItem(i++, 'Module Runtime Information Query', 'runtime','module');
		    
		    createAccordionItem(i++, 'Forwarded Data Query', 'forwardlist','module');
		    
		    createAccordionItem(i++, 'Alert Information List', 'alertlist','alert');
		    createAccordionItem(i++, 'Alert Information Set Processing', 'alertprocess','alert');
		    createAccordionItem(i++, 'Alert Information Delete', 'alertdel','alert');
		    createAccordionItem(i++, 'Alert Information Set Processed', 'alertok','alert');
		    
		    createAccordionItem(i++, 'Configuration Information List', 'configlist','module');
		    createAccordionItem(i++, 'Configuration Information Update', 'configupdate','module');
		    createAccordionItem(i++, 'Configuration Information Delete', 'configdel','module');		    
		}
		function createAccordionItem(id, title, docName,apiUri) {
		     const accordion = document.getElementById('apiAccordion');
		     const accordionItem = document.createElement('div');
		     accordionItem.className = 'accordion-item';
		     accordionItem.id = `item${id}`;

		     const headerHtml = `
		         <h2 class="accordion-header" id="heading${id}">
		             <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" 
		                 data-bs-target="#collapse${id}" aria-expanded="false" aria-controls="collapse${id}" 
		                 onclick="loadAccordionContent('${id}', '${docName}', '${apiUri}')">
		                 <span class="me-2 badge bg-primary">${id}</span> ${title}
		             </button>
		         </h2>
		     `;

		     const contentHtml = `
		         <div id="collapse${id}" class="accordion-collapse collapse" aria-labelledby="heading${id}" data-bs-parent="#apiAccordion">
		             <div class="accordion-body">Loading...</div>
		         </div>
		     `;

		     accordionItem.innerHTML = headerHtml + contentHtml;
		     accordion.appendChild(accordionItem);
		 }

		 function loadAccordionContent(id, docName,apiUri) {
		     const accordionBody = document.querySelector(`#collapse${id} .accordion-body`);
		     if (accordionBody.dataset.loaded === 'true') return;
		     const url='/dc/web/doc?page=api_'+docName+'&apiUri='+apiUri+'&deviceType=dc01';
		     fetch(url)
	         .then((response) => response.ok ? response.text() : Promise.reject('Failed to load content'))
	         .then((content) => {
	        	 const apiInfo = {};
	        	 apiInfo.inputComments=parseContent(content,"inputComments");
	        	 apiInfo.inputDefinition=parseContent(content,"inputDefinition");
	        	 apiInfo.outputComments=parseContent(content,"outputComments");
	        	 apiInfo.outputDefinition=parseContent(content,"outpoutputDefinitionutExample");
	        	 apiInfo.outputExample=parseContent(content,"outputExample");
	        	 apiInfo.protocol=parseContent(content,"protocol");
	        	 apiInfo.jsonContent=parseContent(content,"jsonContent");
	        	 apiInfo.apiKey=parseContent(content,"apiKey");
	        	 var apiRunning=parseContent(content,"apiRunning");
	        	 apiRunning=apiRunning.replace(/&quot;/g, '"');
	        	 apiRunning=JSON.parse(apiRunning);
	             fillAccordionItem(id,apiUri,apiInfo, apiRunning, accordionBody);
	             accordionBody.dataset.loaded = 'true';
	         })
	         .catch((error) => {
        	    accordionBody.innerHTML = 'Error loading content.';
	         });
		 }
       function fillAccordionItem(id,apiUri,apiInfo, apiRunning, bodyDiv) {
    	    let callUri='/dc/api/call?key='+apiInfo.apiKey+'&api='+apiUri;
    	    if(apiInfo.params!=null)
    	    	callUri=callUri+'&'+apiInfo.params;
            bodyDiv.innerHTML  = `
                <strong>Calls | Limit Per Minute:</strong>
                <p>${apiRunning.timesPerMinute || '0'} | ${apiRunning.limitPerMinute || '*'}</p>
                <strong>Calls | Limit Per Day:</strong>
                <p>${apiRunning.timesPerDay || '0'} | ${apiRunning.limitPerDay || '*'}</p>
                <strong>Latest Call:</strong>
                <p>${apiRunning.latestCallTime || ''}</p>
                <strong>Call Times:</strong>
                <p>${apiRunning.calls || ''}</p>
                <strong>Protocol:</strong>
                <p>${apiInfo.protocol}</p>
                <strong>Input:</strong>
                <p>${apiInfo.inputComments || ''}</p>
                <pre>${apiInfo.inputExample || ''}</pre>
                <p>${apiInfo.inputDefinition || ''}</p>
                <strong>Output:</strong>
                <p>${apiInfo.outputComments || ''}</p>
                <pre>${apiInfo.outputExample || ''}</pre>
                <p>${apiInfo.outputDefinition || ''}</p>
                <strong>Example:</strong>
                <pre>${'GET '+callUri}</pre>
                <pre>${apiInfo.jsonContent || ''}</pre>
                <strong>Test:</strong>
                <button class="btn btn-sm p-0" id="${id}TestButton" style="background: none; border: none; color: #007bff; cursor: pointer;">
					<svg class="bi text-primary" width="16" height="16" fill="currentColor">
					  <use href="#server"></use>
					</svg>
                </button>
                <div class="my-2">
                    <textarea id="${id}TestContent" class="form-control" style="white-space: pre; font-family: monospace; padding: 10px; background-color: #f8f9fa;">${callUri || ''}</textarea>
                </div>
                <div id="${id}Result" class="mt-3"></div>
            `;

            document.getElementById(`${id}TestButton`).addEventListener('click', async () => {
                const resultDiv = document.getElementById(`${id}Result`);
                resultDiv.innerHTML = 'Running test...';
                const link = document.getElementById(`${id}TestContent`).value;
                let protocol = apiInfo.protocol === 'GET_POST' || apiInfo.protocol === 'GET' ? 'GET' : 'POST';
                let jsonStr = protocol === 'POST' ? apiInfo.jsonContent || null : null;
                const headers = {
                    'Content-Type': 'application/json'
                };

                function generateResultHtml(link, protocol, headers, jsonStr, responseContent = 'Loading...') {
                    return `
<pre class="bg-dark text-light p-3">
<strong>Link:</strong>
${link}
<strong>Protocol:</strong>
${protocol}
<strong>Header:</strong>
${JSON.stringify(headers, null, 2)}
<strong>Body:</strong>
${jsonStr ? JSON.stringify(JSON.parse(jsonStr), null, 2) : 'None'}
<strong>Response:</strong>
${responseContent}
                    </pre>`;
                }
                resultDiv.innerHTML = generateResultHtml(link, protocol, headers, jsonStr);
                try {
                    const response = await fetch(link, {
                        method: protocol,
                        headers: headers,
                        body: jsonStr ? JSON.stringify(JSON.parse(jsonStr)) : null,
                    });
                    if (response.ok) {
                        const data = await response.json();
                        resultDiv.innerHTML = generateResultHtml(link, protocol, headers, jsonStr, JSON.stringify(data, null, 2));
                    } else {
                        resultDiv.innerHTML = generateResultHtml(link, protocol, headers, jsonStr, `Error: ${response.statusText}`);
                    }
                } catch (error) {
                    resultDiv.innerHTML = generateResultHtml(link, protocol, headers, jsonStr, `Error: ${error.message}`);
                }
            });
        }
    </script>
</body>
</html>